home *** CD-ROM | disk | FTP | other *** search
/ AGA Toolkit '97 / The AGA Toolkit '97.iso / graphics / video&intro / titler / gscroll / gscroll.c < prev    next >
C/C++ Source or Header  |  1996-09-07  |  14KB  |  510 lines

  1. #include <exec/types.h>
  2. #include <exec/memory.h>
  3. #include <exec/libraries.h>
  4. #include <datatypes/datatypes.h>      /* Datatypes definitions we need */
  5. #include <datatypes/pictureclass.h>
  6.  
  7. #include <intuition/intuition.h>
  8. #include <graphics/gfxmacros.h>
  9. #include <dos/var.h>
  10. #include <dos/dos.h>
  11. #include <ifflib/iff.h>
  12. /* #include <libraries/bgui.h> */
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16.  
  17. #include <clib/alib_protos.h>
  18.  
  19. #include <proto/exec.h>
  20. #include <clib/intuition_protos.h>
  21. #include <proto/datatypes.h>
  22. #include <proto/graphics.h>
  23. #include <proto/utility.h>
  24. #include <proto/dos.h>
  25. /* #include <proto/bgui.h>
  26. #include <proto/bitmap.h> */
  27.  
  28. #include <string.h>
  29.  
  30. UBYTE Copyright[]="GScroll. Copyright (C) 1995 by Reinhard Katzmann. All Rights Reserved.";
  31. extern struct Library *IntuitionBase;
  32.  
  33. #define TEMPLATE "IFFFONT/A,TEXTFILE/A,W=WIDTH/K,H=HEIGHT/K,D=DEPTH/K,N=NUMCROW/K,R=ROWS/K,C=CHARS"
  34. #define OPT_IFFFONT        0
  35. #define OPT_TEXTFILE        1
  36. #define OPT_WIDTH            2
  37. #define OPT_HEIGHT        3
  38. #define OPT_DEPTH            4
  39. #define OPT_NUMCROW        5
  40. #define OPT_ROWS            6
  41. #define OPT_CHAR            7
  42. #define OPT_COUNT            8
  43. #define ENVFILE "ENV:gscroll"
  44. #define OSVERSION(ver)    (IntuitionBase->lib_Version >= (ver))
  45. #define HAS_AGA            (GfxBase->ChipRevBits0 & GFXF_AA_ALICE)
  46.  
  47. typedef struct ColBMFont {
  48.     UBYTE        cf_FontWidth;        /* Width of one Charakter                             */
  49.     UBYTE        cf_FontHeight;        /* Height of one Charakter                         */
  50.     UBYTE        cf_FontDepth;        /* Depth of Font                                        */
  51.     UBYTE        cf_CharsPerRow;    /* Number of Charakters in a row                    */
  52.     UBYTE        cf_Rows;                /* Number of rows                                        */
  53.     UBYTE    cf_FontMap[256];    /* Array of all Charakter types in the Font    */
  54.                                         /* If NULL, ASCII is used beginning with 32     */
  55.     struct BitMap *cf_FontBM;    /* Bitmap of Color Font                                */
  56. } COLBMFONT;
  57.  
  58. struct Library    *IFFBase;        /* Nothing goes without that */
  59. struct Window *win;
  60. struct Screen *scr;
  61. struct RDArgs *myrda=NULL;
  62.  
  63. void CloseAll(BOOL ec)
  64. {
  65.     if (win) CloseWindow(win);
  66.     if (myrda) FreeArgs(myrda);
  67.     exit(ec);
  68. }
  69.  
  70. /* 
  71. **        Print out specific IFF error
  72. */
  73. static void PrintIFFError(void)
  74. {
  75.     char *text;
  76.  
  77.     switch (IFFL_IFFError() )
  78.     {
  79.         case IFFL_ERROR_OPEN:
  80.             text = "Can't open file";
  81.             break;
  82.  
  83.         case IFFL_ERROR_READ:
  84.             text = "Error reading file";
  85.             break;
  86.  
  87.         case IFFL_ERROR_NOMEM:
  88.             text = "Not enough memory";
  89.             break;
  90.  
  91.         case IFFL_ERROR_NOTIFF:
  92.             text = "Not an IFF file";
  93.             break;
  94.  
  95.         case IFFL_ERROR_NOBMHD:
  96.             text = "No IFF BMHD found";
  97.             break;
  98.  
  99.         case IFFL_ERROR_NOBODY:
  100.             text = "No IFF BODY found";
  101.             break;
  102.  
  103.         case IFFL_ERROR_BADCOMPRESSION:
  104.             text = "Unsupported compression mode";
  105.             break;
  106.  
  107.         default:
  108.             text = "Unspecified error";
  109.             break;
  110.     }
  111.     printf("%s\n", text);
  112. }
  113.  
  114. /*
  115. ** Free a allocated BitMap
  116. */
  117. void MyFreeBitMap(struct BitMap *bm)
  118. {
  119.     if (OSVERSION(39) )
  120.     {
  121.         FreeBitMap(bm);
  122.     }
  123.     else                    /* Running under V37 */
  124.     {
  125.         LONG    planesize = bm->BytesPerRow * bm->Rows;
  126.         int        i;
  127.  
  128.         for (i = 0; i < bm->Depth; ++i)
  129.         {
  130.             if (bm->Planes[i])
  131.             {
  132.                 FreeMem(bm->Planes[i], planesize);
  133.             }
  134.         }
  135.         FreeVec(bm);
  136.         bm=NULL;
  137.     }
  138. }
  139.  
  140. /*
  141. ** Allocate a BitMap
  142. */
  143. struct BitMap *MyAllocBitMap(LONG depth, LONG width, LONG height, struct BitMap *frbm)
  144. {
  145.     struct BitMap *bm;
  146.  
  147.     if (OSVERSION(39) )
  148.     {
  149.         if (frbm) bm = AllocBitMap(width, height, depth, BMF_CLEAR | BMF_DISPLAYABLE, frbm);
  150.         else bm = AllocBitMap(width, height, depth, BMF_CLEAR | BMF_DISPLAYABLE, NULL);
  151.     }
  152.     else
  153.     {
  154.         LONG planesize, bmsize = sizeof(struct BitMap);
  155.  
  156.         /*
  157.         **    If the bitmap has more than 8 planes, we add the size of the
  158.         **    additional plane pointers to the amount of memory we allocate
  159.         **    for the bitmap structure.
  160.         */
  161.         if (depth > 8)
  162.             bmsize += sizeof(PLANEPTR) * (depth-8);
  163.  
  164.         if (bm = AllocVec(bmsize, MEMF_PUBLIC | MEMF_CLEAR) )
  165.         {
  166.             int i;
  167.  
  168.             InitBitMap(bm, depth, width, height);
  169.             planesize = bm->BytesPerRow * bm->Rows;
  170.  
  171.             for (i = 0; i < depth; ++i)
  172.             {
  173.                 if (bm->Planes[i] = AllocMem(planesize, MEMF_CHIP | MEMF_CLEAR) )
  174.                 {
  175.                 }
  176.                 else
  177.                 {
  178.                     MyFreeBitMap(bm);
  179.                     bm = NULL;
  180.                     break;
  181.                 }
  182.             }
  183.         }
  184.     }
  185.     return bm;
  186. }
  187.  
  188. void ParseEnvFile(COLBMFONT *colfont)
  189. {
  190.     UBYTE co;
  191.     FILE *fp;
  192.     char zeile[256];
  193.     
  194.     fp=fopen(ENVFILE,"r");
  195.     if (!fp) { /* Set defaults */
  196.          colfont->cf_FontWidth=32;
  197.         colfont->cf_FontHeight=32;
  198.         colfont->cf_FontDepth=3;
  199.         colfont->cf_CharsPerRow=10;
  200.         colfont->cf_Rows=6;
  201.         for (co=32;co<255;co++) colfont->cf_FontMap[co]=co-32;
  202.         return;
  203.     }
  204.  
  205.     if (fgets(zeile,256,fp) || !(feof(fp))) colfont->cf_FontWidth=(UBYTE)atol(zeile);
  206.     
  207.     if (fgets(zeile,256,fp) || !(feof(fp))) colfont->cf_FontHeight=(UBYTE)atol(zeile);
  208.     
  209.     if (fgets(zeile,256,fp) || !(feof(fp))) colfont->cf_FontDepth=(UBYTE)atol(zeile);
  210.     
  211.     if (fgets(zeile,256,fp) || !(feof(fp))) colfont->cf_CharsPerRow=(UBYTE)atol(zeile);
  212.         
  213.     if (fgets(zeile,256,fp) || !(feof(fp))) colfont->cf_Rows=(UBYTE)atol(zeile);
  214.     
  215.     if (fgets(zeile,256,fp) || !(feof(fp))) {
  216.         for (co=0;co<strlen(zeile);co++) colfont->cf_FontMap[(UBYTE)zeile[co]]=co;
  217.     }
  218.  
  219.     fclose(fp);
  220. }
  221.  
  222. BOOL PicLoad(char *fontfile, struct BitMap *bm)
  223. /* Load an IFF Font file from disk */
  224. {
  225.     IFFL_HANDLE    ifffile;    /* IFF file handle */
  226.     struct IFFL_BMHD        *bmhd;
  227.  
  228.     if (! (IFFBase = OpenLibrary(IFFNAME, 19L)) ) {
  229.         printf("Could not open iff.library.\n");
  230.         return FALSE;
  231.     }
  232.  
  233.     if ( !(ifffile = IFFL_OpenIFF(fontfile, IFFL_MODE_READ)) )
  234.     {
  235.         PrintIFFError();
  236.         return FALSE;
  237.     }
  238.  
  239.     if ( *(((ULONG *)ifffile)+2) != ID_ILBM)
  240.     {
  241.         printf("Not an ILBM picture\n");
  242.         return FALSE;
  243.     }
  244.  
  245.     if ( !(bmhd = IFFL_GetBMHD(ifffile)) )
  246.     {
  247.         PrintIFFError();
  248.         return FALSE;
  249.     }
  250.  
  251.     /* Colortable is ignored, this is only a small example :-) */
  252.     
  253.     if (! (IFFL_DecodePic(ifffile, bm) ) )
  254.     {
  255.       printf("FATAL: Could not decode picture.\n");
  256.       PrintIFFError();
  257.       if(ifffile) IFFL_CloseIFF(ifffile);
  258.       CloseAll(FALSE);
  259.     }
  260.  
  261.     /* All went well, so we can close the file */
  262.     if(ifffile) IFFL_CloseIFF(ifffile);    
  263.  
  264.     if (IFFBase) CloseLibrary(IFFBase);
  265.     return TRUE;
  266. }
  267.  
  268. BOOL CheckMsgs(APTR dto, char **line, UBYTE zz, struct BitMap *bm)
  269. {
  270.     UBYTE co;
  271.     ULONG MessageClass;
  272.     struct IntuiMessage     *botschaft;
  273.  
  274.     if ((botschaft = (struct IntuiMessage *)
  275.         GetMsg(win->UserPort)) != NULL)
  276.     {
  277.         MessageClass = botschaft->Class;
  278.         ReplyMsg((struct Message *)botschaft);
  279.         switch (MessageClass)
  280.         {
  281.             case IDCMP_CLOSEWINDOW: for (co=0;co<zz;co++) if (line[co]) FreeVec(line[co]);
  282.                                             if (dto) DisposeDTObject(dto);
  283.                                             else if (bm) MyFreeBitMap(bm);
  284.                                             CloseAll(TRUE);
  285.                                             break;
  286.  
  287.             case IDCMP_NEWSIZE: RectFill(win->RPort,win->BorderLeft+1,win->BorderTop+1,win->Width-win->BorderLeft-win->BorderRight+1,win->Height-win->BorderBottom-3);
  288.             case IDCMP_CHANGEWINDOW: return TRUE;
  289.                                              break;
  290.         }
  291.     }
  292.     return FALSE;
  293. }
  294.  
  295. void main(int argc, char **argv)
  296. {
  297.     COLBMFONT colfont={0,0,0,0,0,NULL,NULL};
  298.     UBYTE zz=0,co,ca,cu=0;
  299.     ULONG left,top,width,height,wleft,wtop;
  300.     LONG      result[OPT_COUNT]={NULL,NULL},pen;
  301.     struct ColorRegister *cmap;
  302.     struct          WBStartup *startup=NULL;
  303.     struct ViewPort *VP;
  304.     struct dtFrameBox mydtFrameBox; /* Use this with DTM_FRAMEBOX method   */
  305.     struct FrameInfo myFrameInfo;   /* For info returned from DTM_FRAMEBOX */
  306.     struct gpLayout mygpLayout;     /* Use this with DTM_PROCLAYOUT method */
  307.     char *ifffile,*textfile,*line[20],carr[256],zeile[256];
  308.     APTR dtobject=NULL; /* Pointer to a datatypes object       */
  309.     FILE *tfp;
  310.   
  311.    if (argc==0) startup = (struct WBStartup *)argv;
  312.     if (!startup) printf("%s\n",Copyright);
  313.    if (argc==2 && !strcmp(argv[1],"?")) {
  314.       printf("Usage: %s %s\n",argv[0],TEMPLATE);
  315.       exit(TRUE);
  316.    }
  317.  
  318.    if (!(myrda=ReadArgs(TEMPLATE, result, NULL))) {
  319.       if (!startup) puts("Could not parse arguments.");
  320.       CloseAll(FALSE);
  321.    }
  322.  
  323.     if (!result[OPT_IFFFONT]) {
  324.         printf("Required argument missing.\n");
  325.         CloseAll(FALSE);
  326.     } else ifffile=(char *)result[OPT_IFFFONT];
  327.  
  328.     if (!result[OPT_TEXTFILE]) {
  329.         printf("Required argument missing.\n");
  330.         CloseAll(FALSE);
  331.     } else textfile=(char *)result[OPT_TEXTFILE];
  332.  
  333.     ParseEnvFile(&colfont);
  334.  
  335.     if (result[OPT_WIDTH]) colfont.cf_FontWidth=(UBYTE)atol((char *)result[OPT_WIDTH]);
  336.     
  337.     if (result[OPT_HEIGHT]) colfont.cf_FontHeight=(UBYTE)atol((char *)result[OPT_HEIGHT]);
  338.     
  339.     if (result[OPT_DEPTH]) colfont.cf_FontDepth=(UBYTE)atol((char *)result[OPT_DEPTH]);
  340.     
  341.     if (result[OPT_NUMCROW]) colfont.cf_CharsPerRow=(UBYTE)atol((char *)result[OPT_NUMCROW]);
  342.         
  343.     if (result[OPT_ROWS]) colfont.cf_Rows=(UBYTE)atol((char *)result[OPT_ROWS]);
  344.     
  345.     if (result[OPT_CHAR]) {
  346.         strcpy(carr,(char *)result[OPT_CHAR]);
  347.         for (co=0;co<strlen(carr);co++) colfont.cf_FontMap[carr[co]]=co;
  348.     }
  349.  
  350.     if (!(scr=LockPubScreen(NULL)))
  351.    {
  352.        if (!startup) puts("Could not lock Public Screen.");
  353.        CloseAll(FALSE);
  354.       }
  355.  
  356.     if (OSVERSION(39) ) {
  357.         if (!(dtobject = NewDTObject(ifffile, PDTA_Screen, scr,
  358.                          DTA_GroupID, GID_PICTURE,
  359.                          TAG_END) )) {
  360.            printf("Couldn't create new object or not a picture file\n");
  361.            CloseAll(FALSE);
  362.        }
  363.         mydtFrameBox.MethodID         = DTM_FRAMEBOX;
  364.         mydtFrameBox.dtf_GInfo        = NULL;
  365.         mydtFrameBox.dtf_ContentsInfo = NULL;
  366.         mydtFrameBox.dtf_FrameInfo    = &myFrameInfo;
  367.         mydtFrameBox.dtf_SizeFrameInfo= sizeof (struct FrameInfo);
  368.         mydtFrameBox.dtf_FrameFlags   = 0L;
  369.         DoMethodA(dtobject, (Msg)&mydtFrameBox);
  370.  
  371.         mygpLayout.MethodID   = DTM_PROCLAYOUT;
  372.         mygpLayout.gpl_GInfo  = NULL;
  373.         mygpLayout.gpl_Initial= 1L;
  374.  
  375.         if(!(DoMethodA(dtobject, (Msg)&mygpLayout) )) {
  376.             printf("Couldn't perform PROC_LAYOUT\n");
  377.             if (dtobject) DisposeDTObject(dtobject);
  378.             CloseAll(FALSE);
  379.         }
  380.         GetDTAttrs(dtobject, PDTA_DestBitMap, &colfont.cf_FontBM,
  381.                                     PDTA_ColorRegisters,    &cmap, 
  382.                                     TAG_END);
  383.     } else { /* Now the hard work :-( */
  384.         colfont.cf_FontBM=MyAllocBitMap(colfont.cf_FontDepth,colfont.cf_FontWidth*colfont.cf_CharsPerRow,colfont.cf_FontHeight*colfont.cf_Rows,NULL);
  385.         if (!colfont.cf_FontBM) {
  386.             printf("Could not allocate BitMap\n");
  387.             CloseAll(FALSE);
  388.         }
  389.  
  390.           if (!PicLoad(ifffile,colfont.cf_FontBM)) {
  391.             printf("Could not load IFF File.\n");
  392.             MyFreeBitMap(colfont.cf_FontBM);
  393.             CloseAll(FALSE);
  394.         }
  395.     
  396.     }
  397.  
  398.     /* Font file has now been loaded */
  399.  
  400.     tfp=fopen(textfile,"r");
  401.     if (!tfp) {
  402.         printf("Could not open Text file for reading.\n");
  403.         if (dtobject) DisposeDTObject(dtobject);
  404.         else if (colfont.cf_FontBM) MyFreeBitMap(colfont.cf_FontBM);
  405.         CloseAll(FALSE);
  406.     }
  407.  
  408.     VP=&scr->ViewPort;
  409.  
  410.     win = OpenWindowTags(NULL,
  411.                 WA_Flags,
  412.                WFLG_CLOSEGADGET |
  413.                WFLG_SIZEGADGET |
  414.                WFLG_DRAGBAR |
  415.                WFLG_DEPTHGADGET |
  416.                WFLG_SMART_REFRESH |
  417.                WFLG_ACTIVATE,
  418.             WA_IDCMP,
  419.                IDCMP_NEWSIZE |
  420.                IDCMP_CHANGEWINDOW |
  421.                IDCMP_CLOSEWINDOW,
  422.             WA_Left, 50,
  423.             WA_Top, 100,
  424.             WA_InnerWidth,640,
  425.             WA_InnerHeight,colfont.cf_FontHeight+20,
  426.             WA_MinWidth, colfont.cf_FontWidth,
  427.             WA_MinHeight, colfont.cf_FontHeight+20,
  428.             WA_MaxWidth, scr->Width,
  429.             WA_MaxHeight, scr->Height,
  430.             WA_Title, "Scroller Demo",
  431.             WA_PubScreen, scr,
  432.             TAG_DONE);
  433.    if (!win) {
  434.        printf("Could not open Window.\n");
  435.         if (dtobject) DisposeDTObject(dtobject);
  436.         else if (colfont.cf_FontBM) MyFreeBitMap(colfont.cf_FontBM);
  437.         fclose(tfp);
  438.        CloseAll(FALSE);
  439.    }
  440.  
  441.     
  442.     width=win->Width-win->BorderLeft-win->BorderRight;
  443.     height=colfont.cf_FontHeight;
  444.     wleft=win->LeftEdge+win->BorderLeft;
  445.     wtop=win->TopEdge+win->BorderTop;
  446.  
  447.     if (OSVERSION(39) ) {
  448.         pen=ObtainBestPen(VP->ColorMap,cmap->red<<24,cmap->green<<24,cmap->blue<<24,TAG_DONE);
  449.         SetAPen(win->RPort, pen);
  450.         SetBPen(win->RPort, pen);
  451.         RectFill(win->RPort,win->BorderLeft+1,win->BorderTop+1,width+1,win->Height-win->BorderBottom-3);
  452.     }
  453.  
  454.     while (fgets(zeile,256,tfp) || !(feof(tfp)) ) {
  455.         if (zz>=20) continue;
  456.         if (!strcmp(zeile,"\n")) continue;
  457.         line[zz]=AllocVec(strlen(zeile),MEMF_PUBLIC|MEMF_CLEAR);
  458.         if (line[zz]) {
  459.             strcpy(line[zz],zeile);
  460.             zz++;
  461.         }
  462.     }
  463.     fclose(tfp);
  464.  
  465.     /* Now we can start scrolling the text */
  466.  
  467.     for (co=0;co<zz;co++) { /* All lines */
  468.         for (ca=0;ca<(strlen(line[co])-1);ca++) { /* All Charakters of a line */
  469.             if (line[co][ca]=='\t') line[co][ca]=' ';
  470.             if (!colfont.cf_FontMap[line[co][ca]]) continue;
  471.             left=colfont.cf_FontWidth*(colfont.cf_FontMap[line[co][ca]]%colfont.cf_CharsPerRow);
  472.             top=colfont.cf_FontHeight*(colfont.cf_FontMap[line[co][ca]]/colfont.cf_CharsPerRow);
  473.             for(cu=0;cu<colfont.cf_FontWidth;cu++) { /* Scroll all pixels of a charakter */
  474.                 if (CheckMsgs(dtobject,line,zz,colfont.cf_FontBM)) {
  475.                     width=win->Width-win->BorderLeft-win->BorderRight;
  476.                     wleft=win->LeftEdge+win->BorderLeft;
  477.                     wtop=win->TopEdge+win->BorderTop;
  478.                 }
  479.                 BltBitMap(colfont.cf_FontBM,left+cu,top,win->RPort->BitMap,wleft+width-3,wtop+3,1,colfont.cf_FontHeight,0xC0,0xFF,NULL);
  480.                 ScrollRaster(win->RPort,1,0,win->BorderLeft+1,win->BorderTop+1,win->BorderLeft+width-3,win->BorderTop+height+1);
  481.                 /* Delay(1); */
  482.                 
  483.             }
  484.         }
  485.     }
  486.     
  487.     /* Text has been scrolled, now lets scroll the text out of the window */
  488.  
  489.     left=colfont.cf_FontWidth*(colfont.cf_FontMap[' ']%colfont.cf_CharsPerRow);
  490.     top=colfont.cf_FontHeight*(colfont.cf_FontMap[' ']/colfont.cf_CharsPerRow);
  491.     /* BltBitMap(colfont.cf_FontBM,0,0,win->RPort->BitMap,wleft,wtop,colfont.cf_FontWidth*colfont.cf_CharsPerRow,colfont.cf_FontHeight*colfont.cf_Rows,0xC0,0xFF,NULL); */
  492.     for (co=0;co<(win->Width/colfont.cf_FontWidth);co++) {
  493.         for(cu=0;cu<colfont.cf_FontWidth;cu++) { /* Scroll all pixels of a charakter */
  494.             if (CheckMsgs(dtobject,line,zz,colfont.cf_FontBM)) {
  495.                 width=win->Width-win->BorderLeft-win->BorderRight;
  496.                 wleft=win->LeftEdge+win->BorderLeft;
  497.                 wtop=win->TopEdge+win->BorderTop;
  498.             }
  499.             BltBitMap(colfont.cf_FontBM,left+cu,top,win->RPort->BitMap,wleft+width-3,wtop+3,1,colfont.cf_FontHeight,0xC0,0xFF,NULL);
  500.             ScrollRaster(win->RPort,1,0,win->BorderLeft+1,win->BorderTop+1,win->BorderLeft+width-3,win->BorderTop+height+1);
  501.         }
  502.     }
  503.  
  504.     /* Clean up */
  505.     for (co=0;co<zz;co++) if (line[co]) FreeVec(line[co]);
  506.     if (dtobject) DisposeDTObject(dtobject);
  507.     else if (colfont.cf_FontBM) MyFreeBitMap(colfont.cf_FontBM);
  508.       CloseAll(TRUE);
  509. }
  510.